{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "import time\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "N = 5 * 500 * 500"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.array(np.random.randn(N), dtype=np.float32)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## pytorch ops"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.36 ms ± 48.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<TimeitResult : 1.36 ms ± 48.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%timeit -o\n",
    "Xt = torch.tensor(x).cuda()\n",
    "torch.cuda.synchronize()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "pytorch = {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "torch_gputransfert = np.array(_.timings)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.44 ms ± 11.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<TimeitResult : 1.44 ms ± 11.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%timeit -o\n",
    "Xt = torch.tensor(x).cuda()\n",
    "torch.cumsum(Xt, 0)\n",
    "torch.cuda.synchronize()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "pytorch['cumsum'] = np.array(_.timings) - torch_gputransfert"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5.21 ms ± 75.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<TimeitResult : 5.21 ms ± 75.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%timeit -o\n",
    "Xt = torch.tensor(x).cuda()\n",
    "torch.sort(Xt, 0)\n",
    "torch.cuda.synchronize()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "pytorch['sort'] = np.array(_.timings) - torch_gputransfert"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tensorflow ops"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = tf.placeholder(tf.float32, shape=(None,), name=None)\n",
    "Y = tf.cumsum(X)\n",
    "Z = tf.nn.top_k(X, tf.shape(X)[0])\n",
    "A = tf.identity(X)\n",
    "\n",
    "config = tf.ConfigProto()\n",
    "config.gpu_options.allow_growth=True\n",
    "\n",
    "sess = tf.Session(config=config)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.59 ms ± 44.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<TimeitResult : 1.59 ms ± 44.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%timeit -o\n",
    "sess.run(A, feed_dict={X: x})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "tensf = {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "tf_gputransfert = np.array(_.timings)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "330 ms ± 1.36 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<TimeitResult : 330 ms ± 1.36 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%timeit -o\n",
    "sess.run(Y, feed_dict={X: x})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "tensf['cumsum'] = np.array(_.timings) - tf_gputransfert"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10.9 ms ± 36.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<TimeitResult : 10.9 ms ± 36.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)>"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%timeit -o\n",
    "sess.run(Z, feed_dict={X: x})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "tensf['sort'] = np.array(_.timings) - tf_gputransfert"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Summary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5,1,'timings (1250000 pixels)')"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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48MPP+SDDz7gD3/4A4cffvhn2j/00EN54oknePXVVwF49913s39TReA9DjMre1kcPpuPvffem1tvvZVvfvOb9O3bl29961sADB8+nBUrVrDPPvtsXHbMmDHU1NQwcOBAJk+ezMiRIznooIMAOO+88xgwYABLly79VPvdunVjwoQJDBs2jA0bNrDzzjvz2GOPtdn721QVec/x2tra8I2c8HkctsVauHAhe++9d0lrWLp0Kccffzzz58//zLyLLrqIAQMGcO6555agsuJo6jOWNDsialtb13scZmYFOOCAA+jYsSPXXnttqUspGQeHmVkTqqurm9zbmD17dgmqKS8VNTjuEwDNzLJXUcHhEwDNzLJXUcFhZmbZc3CYmVlBPDhuZuWv2IeW53F496pVq7jjjju44IILirvtPJ1++uksWLCAUaNG8fzzz3P88cdzyimnlKSWxrzHYWbWhFWrVnHjjTe2+Xbr6+t56623+Mtf/sK8efO4+OKL27yG1jg4zMyaMHbsWF5++WX69+/P9773Pa655hoOPPBAampquOKKK4BPLpM+evRo9t13X4YMGcLatWsBuP7669lnn32oqanhtNNOA5JLipx00knU1NRwyCGHMG/ePCC5cdOYMWMYMmQII0aMYMiQISxfvpz+/ftvvDhig8cff5wBAwaw3377cc455/DRRx8xc+ZMhg0bBsD999/Ptttuy8cff8y6devo3bt30T8bB4eZWRPGjx/P7rvvzty5czn66KNZvHgxM2fOZO7cucyePZvp06cDsHjxYi688EIWLFjAjjvuyL333rtx/Tlz5jBv3jxuuukmAK644goGDBjAvHnzuOqqqxgxYsTG7c2ePZv777+fO+64gylTpmzcdu41rtatW8fIkSO56667eOGFF6ivr+eXv/wlAwcO3HjZ9ieffJJ+/foxa9Ysnn32WQ4++OCifzYODjOzVjz66KM8+uijDBgwgIEDB7Jo0SIWL14MQK9evejfvz+QnFXecD2qmpoahg8fzu23377xCrozZszgrLPOAuDII49k5cqVNJx3dsIJJ7Dtttu2WMdLL71Er1692GOPPQA4++yzmT59Ou3bt6dPnz4sXLiQmTNncskllzB9+nSefPLJJi+uuLkcHGZmrYgILr30UubOncvcuXNZsmTJxutUNXf586lTp3LhhRcye/ZsDjjgAOrr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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "r = 1/2\n",
    "x = np.arange(len(pytorch))\n",
    "funs = pytorch.keys()\n",
    "\n",
    "plt.bar(x - r/4, [v.mean() for v in pytorch.values()], width=r/2, yerr=[v.std() for v in pytorch.values()], label='pytorch')\n",
    "plt.bar(x + r/4, [v.mean() for v in tensf.values()], width=r/2, yerr=[v.std() for v in tensf.values()], label='tensorflow')\n",
    "plt.legend()\n",
    "plt.gca().set_yscale('log')\n",
    "plt.xticks(x, funs);\n",
    "plt.ylabel('time (s)')\n",
    "plt.savefig('timings.svg')\n",
    "plt.title('timings ({} pixels)'.format(N))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:neural7]",
   "language": "python",
   "name": "conda-env-neural7-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
